package executor

import (
	"smart-flow/server/config"
	"smart-flow/server/net"
	"sync"

	cmap "github.com/orcaman/concurrent-map"
)

var (
	executingCtOnce sync.Once
	executingCmOnce sync.Once
	executingCuOnce sync.Once
	executingOnce   sync.Once
	executingCt     *Executing
	executingCm     *Executing
	executingCu     *Executing
	executing       *Executing
)

type Executing struct {
	executors      cmap.ConcurrentMap
	notV6executors cmap.ConcurrentMap
}

func ExecutingInstance(isp string) *Executing {
	switch isp {
	case config.IspTelecom:
		executingCtOnce.Do(func() {
			executingCt = &Executing{
				executors:      cmap.New(),
				notV6executors: cmap.New(),
			}
		})
		return executingCt
	case config.IspMobile:
		executingCmOnce.Do(func() {
			executingCm = &Executing{
				executors:      cmap.New(),
				notV6executors: cmap.New(),
			}
		})
		return executingCm
	case config.IspUnicom:
		executingCuOnce.Do(func() {
			executingCu = &Executing{
				executors:      cmap.New(),
				notV6executors: cmap.New(),
			}
		})
		return executingCu
	default:
		executingOnce.Do(func() {
			executing = &Executing{
				executors:      cmap.New(),
				notV6executors: cmap.New(),
			}
		})
		return executing
	}
}

func (e *Executing) AddExecutor(uid string, agentCtx *net.AgentContext) {
	e.executors.Set(uid, agentCtx)
}

func (e *Executing) GetExecutor(uid string) *net.AgentContext {
	val, exist := e.executors.Get(uid)
	if !exist {
		return nil
	}
	return val.(*net.AgentContext)
}

func (e *Executing) DelExecutor(uid string) {
	e.executors.Remove(uid)
}

func (e *Executing) ExistExecutor(uid string) bool {
	return e.executors.Has(uid)
}

func (e *Executing) AddNotV6Executor(uid string, agentCtx *net.AgentContext) {
	e.notV6executors.Set(uid, agentCtx)
}

func (e *Executing) GetNotV6Executor(uid string) *net.AgentContext {
	val, exist := e.notV6executors.Get(uid)
	if !exist {
		return nil
	}
	return val.(*net.AgentContext)
}

func (e *Executing) DelNotV6Executor(uid string) {
	e.notV6executors.Remove(uid)
}

func (e *Executing) ExistNotV6Executor(uid string) bool {
	return e.notV6executors.Has(uid)
}
